/**
 * Copyright (c) 2018-2028, LookAhead.
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.lookahead.parent.common.utils;

import org.lookahead.parent.common.exceptions.Exceptions;
import org.springframework.lang.Nullable;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * 加密相关工具类直接使用Spring util封装，减少jar依赖
 *
 * @author LookAhead
 */
public class DigestUtil extends org.springframework.util.DigestUtils {

    /**
     * Calculates the MD5 digest and returns the value as a 32 character hex string.
     *
     * @param data Data to digest
     * @return MD5 digest as a hex string
     */
    public static String md5Hex(final String data) {
        return DigestUtil.md5DigestAsHex(data.getBytes(UTF_8));
    }

    /**
     * Return a hexadecimal string representation of the MD5 digest of the given bytes.
     *
     * @param bytes the bytes to calculate the digest over
     * @return a hexadecimal digest string
     */
    public static String md5Hex(final byte[] bytes) {
        return DigestUtil.md5DigestAsHex(bytes);
    }

    private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();

    public static String sha1(String srcStr) {
        return hash("SHA-1", srcStr);
    }

    public static String sha256(String srcStr) {
        return hash("SHA-256", srcStr);
    }

    public static String sha384(String srcStr) {
        return hash("SHA-384", srcStr);
    }

    public static String sha512(String srcStr) {
        return hash("SHA-512", srcStr);
    }

    public static String hash(String algorithm, String srcStr) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            byte[] bytes = md.digest(srcStr.getBytes(UTF_8));
            return toHex(bytes);
        } catch (NoSuchAlgorithmException e) {
            throw Exceptions.unchecked(e);
        }
    }

    public static String toHex(byte[] bytes) {
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        for (byte aByte : bytes) {
            ret.append(HEX_DIGITS[(aByte >> 4) & 0x0f]);
            ret.append(HEX_DIGITS[aByte & 0x0f]);
        }
        return ret.toString();
    }

    public static boolean slowEquals(@Nullable String a, @Nullable String b) {
        if (a == null || b == null) {
            return false;
        }
        return slowEquals(a.getBytes(UTF_8), b.getBytes(UTF_8));
    }

    public static boolean slowEquals(@Nullable byte[] a, @Nullable byte[] b) {
        if (a == null || b == null) {
            return false;
        }
        if (a.length != b.length) {
            return false;
        }
        int diff = a.length ^ b.length;
        for (int i = 0; i < a.length && i < b.length; i++) {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }

    /**
     * 自定义加密 先MD5再SHA1
     *
     * @param data 数据
     * @return String
     */
    public static String encrypt(String data) {
        return sha1(md5Hex(data));
    }

    /**
     * 自定义加密 先MD5 加密获取16位并转大写
     *
     * @param data 数据
     * @return String
     */
    public static String md5_16bit(String data) {
        return md5Hex(data).substring(8, 24).toUpperCase(Locale.ROOT);
    }


    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        System.out.println(encrypt("zxwljy2022@LOOKAHEAD#SCHOOLAPPLET"));
        //zxwljy2022@LOOKAHEAD#SCHOOLAPPLET - 585b7f434bef0944803bfbe614e2a58557c39b5f
        //zxwljy2021@LOOKAHEAD#STUDENT - 81b6970a59e31b56c8d2fdc92a8f06860a57208f
    }

}
